package com.kjlink.internal.workreport.config.db;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * 描述:
 * jdbcTemplate配置
 * 多数据源会导致 MybatisAutoConfiguration不生效，因为存在这样的注解：@ConditionalOnSingleCandidate(DataSource.class)
 *
 * @author Vic.xu
 * @since 2024-05-10 9:53
 */
@Configuration
public class JdbcTemplateConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(JdbcTemplateConfig.class);

    /**
     * 工银的jira 数据源
     */
    public static final String JIRA_JDBC_TEMPLATE = "jiraJdbcTemplate";
    /**
     * 非工银 jira 数据源
     */
    public static final String JIRA2_JDBC_TEMPLATE = "jira2JdbcTemplate";


    private JiraDataSourceProperties jiraDataSourceProperties;

    private Jira2DataSourceProperties jira2DataSourceProperties;

    public JdbcTemplateConfig(JiraDataSourceProperties jiraDataSourceProperties, Jira2DataSourceProperties jira2DataSourceProperties) {
        this.jiraDataSourceProperties = jiraDataSourceProperties;
        this.jira2DataSourceProperties = jira2DataSourceProperties;
    }

    /**
     * 默认的JdbcTemplate
     */
    @Bean
    @Primary
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        LOGGER.info("create default JdbcTemplate");
        return new JdbcTemplate(dataSource);
    }


    /**
     * jira JdbcTemplate
     */
    @Bean(name = JIRA_JDBC_TEMPLATE)
    public JdbcTemplate jiraJdbcTemplate() {
        LOGGER.info("create jira JdbcTemplate");
        return buildJdbcTemplate(jiraDataSourceProperties);
    }

    /**
     * jira2 JdbcTemplate
     */
    @Bean(name = JIRA2_JDBC_TEMPLATE)
    public JdbcTemplate jira2JdbcTemplate() {
        LOGGER.info("create jira2 JdbcTemplate");
        return buildJdbcTemplate(jira2DataSourceProperties);
    }

    /**
     * 根据数据源构件置JdbcTemplate
     *
     * @param dataSourceProperties DataSourceProperties
     * @return JdbcTemplate
     */
    private JdbcTemplate buidlJdbcTemplate(org.springframework.boot.autoconfigure.jdbc.DataSourceProperties dataSourceProperties) {
        HikariConfig config = new HikariConfig();
        // 设置数据库连接信息
        config.setDriverClassName(dataSourceProperties.getDriverClassName());
        config.setJdbcUrl(dataSourceProperties.getUrl());
        config.setUsername(dataSourceProperties.getUsername());
        config.setPassword(dataSourceProperties.getPassword());
        // 配置HikariCP的连接池参数
        // 连接池最大连接数
        config.setMaximumPoolSize(10);
        // 最小空闲连接数
        config.setMinimumIdle(5);
        // 空闲连接超时时间，单位毫秒
        config.setIdleTimeout(60000);
        // 连接最大生命周期，单位毫秒
        config.setMaxLifetime(1800000);
        // 测试连接是否可用的SQL语句
        config.setConnectionTestQuery("SELECT 1");
        config.setConnectionTimeout(10000);
        HikariDataSource hikariDataSource = new HikariDataSource(config);
        return new JdbcTemplate(hikariDataSource);
    }

    /**
     * DataSourceBuilder 是 Spring Boot 提供的一个用于构建数据源（DataSource）的工具类。它内部的实现机制遵循了 Spring 框架对于管理组件的相关规范和约定，
     * 会将构建出来的数据源实例按照 Spring 的管理方式进行注册，使其融入到 Spring 的整个应用上下文（ApplicationContext）环境中。
     */
    private JdbcTemplate buildJdbcTemplate(org.springframework.boot.autoconfigure.jdbc.DataSourceProperties dataSourceProperties) {
        // 使用DataSourceBuilder根据配置属性构建数据源，它会自动适配Spring Boot的管理机制
        HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create()
                .url(dataSourceProperties.getUrl())
                .username(dataSourceProperties.getUsername())
                .password(dataSourceProperties.getPassword())
                .driverClassName(dataSourceProperties.getDriverClassName())
                .type(HikariDataSource.class)
                .build();
        // 设置 connectionTestQuery
        dataSource.setConnectionTestQuery("SELECT 1");
        return new JdbcTemplate(dataSource);
    }


}
